package com.gavindon.android.widget.banner

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Color
import android.graphics.RectF
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.StateListDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.util.AttributeSet
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.constraintlayout.utils.widget.ImageFilterView
import androidx.core.view.setPadding
import com.bumptech.glide.Glide
import com.gavindon.android.R
import com.gavindon.android.utils.click
import com.gavindon.android.utils.clickFree
import com.gavindon.android.widget.FocusViewUtils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.jetbrains.anko.dip
import org.jetbrains.anko.matchParent
import java.util.concurrent.TimeUnit


/**
 * description: 首页轮播
 * Created by liNan on  2022-2-19 13:55
 */
class BannerView : FrameLayout {

    private var mDisposable: Disposable? = null
    private val normalDotSize = dip(10)

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        //设置背景放大效果
//        background = stateListDrawable()
        FocusViewUtils.scaleView(this, 2)
        this.clickFree {
            clickListener?.invoke(currentIndex)
        }
    }

    private var lastIndex = 0
    private var currentIndex = 0

    fun addViews(arg: List<String>) {
        arg.forEachIndexed { index, url ->
            val imageView = ImageFilterView(this.context)
            imageView.round = dip(10).toFloat()
            imageView.scaleType = ImageView.ScaleType.FIT_XY
            imageView.layoutParams = LayoutParams(matchParent, matchParent)
            Glide.with(this).load(url)
                .centerCrop()
                .into(imageView)
            addView(imageView)
            if (index != 0) {
                imageView.visibility = View.GONE
            }
        }
        addDots()
    }

    private var clickListener: ((Int) -> Unit)? = null
    fun addOnItemClickListener(listener: (Int) -> Unit) {
        clickListener = listener
    }

    /**
     * 根据childView数量添加指示小圆点
     */
    private fun addDots() {
        val linearLayout = LinearLayout(this.context)
        linearLayout.setPadding(dip(20))
        linearLayout.clipToPadding = false
        linearLayout.clipChildren = false
        val lp = LayoutParams(
            LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT, Gravity.BOTTOM
                    or Gravity.CENTER
        )
        for (i in 0 until childCount) {
            val textView = View(this.context)
            val dotLp = LinearLayout.LayoutParams(normalDotSize, normalDotSize)
            dotLp.marginStart = dip(6)
            textView.setBackgroundResource(R.drawable.no_dot)
            dotLp.gravity = Gravity.CENTER
            linearLayout.addView(textView, dotLp)
            if (i == 0) {
                textView.isSelected = true
                dotFat(textView, null)
            }
        }
        addView(linearLayout, lp)
    }

    fun startFlipper() {
        mDisposable = Observable.interval(8, 8, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                //childCount -1
                currentIndex = if (lastIndex + 1 == childCount - 1) 0 else lastIndex + 1
                val currentView = getChildAt(currentIndex)
                val lastView = getChildAt(lastIndex)
                val exitAnim =
                    ObjectAnimator.ofFloat(lastView, "translationX", 0f, -width.toFloat())
                val enterAnim =
                    ObjectAnimator.ofFloat(currentView, "translationX", width.toFloat(), 0f)
                val animatorSet = AnimatorSet()
                animatorSet.duration = 600
                animatorSet.interpolator = AccelerateDecelerateInterpolator()
                animatorSet.playTogether(exitAnim, enterAnim)
                animatorSet.start()
                //指示点布局
                val llDots = getChildAt(childCount - 1) as LinearLayout
                val lastDot = llDots.getChildAt(lastIndex)
                val currentDot = llDots.getChildAt(currentIndex)
                lastDot.isSelected = false
                currentDot.isSelected = true
                dotFat(currentDot, lastDot)
                currentView.visibility = View.VISIBLE
                lastIndex = currentIndex
            }

    }


    private var gradientColor: IntArray = intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT)

    /**
     * View背景 根据状态切换
     */
    private fun stateListDrawable(): StateListDrawable {
        val stateListDrawable = StateListDrawable()
        //焦点效果
        stateListDrawable.addState(
            intArrayOf(android.R.attr.state_focused),
            effect()
        )
        //默认效果
        stateListDrawable.addState(
            intArrayOf(),
            getGradientDrawable()
        )
        return stateListDrawable
    }

    private fun getGradientDrawable(): GradientDrawable {
        val gradientDrawable =
            GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, gradientColor)
        gradientDrawable.cornerRadius = dip(10).toFloat()
        return gradientDrawable
    }

    private fun effect(): LayerDrawable {
        // 外部矩形弧度
        val corner = dip(10).toFloat()
        val outerR = floatArrayOf(corner, corner, corner, corner, corner, corner, corner, corner)
        // 内部矩形与外部矩形的距离
        val inset = RectF(0f, 0f, 0f, 0f)
        // 内部矩形弧度
        val innerRadii =
            floatArrayOf(corner, corner, corner, corner, corner, corner, corner, corner)
        val shapeDrawable = ShapeDrawable(RoundRectShape(outerR, null, null))
        shapeDrawable.paint.color = Color.WHITE
        val layers = arrayOf(shapeDrawable, getGradientDrawable())
        val layerDrawable = LayerDrawable(layers)
        layerDrawable.setLayerInset(0, -2, -2, -2, -2)

        return layerDrawable
    }

    override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
        return super.dispatchKeyEvent(event)
    }

    fun stopInterval() {
        mDisposable?.dispose()
    }

    /**
     * 指示圆点增大缩小 )
     */
    private fun dotFat(dotView: View, lastDotView: View?) {
        val scaleX1 = 1.3f
        dotView.animate()
            .scaleXBy(1f)
            .scaleX(scaleX1)
            .scaleYBy(1f)
            .scaleY(scaleX1)
            .zBy(0f)
            .z(1f)
            .setInterpolator(AccelerateDecelerateInterpolator()).duration = 100

        lastDotView?.let {
            it.animate()
                .scaleXBy(scaleX1)
                .scaleX(1f)
                .scaleYBy(scaleX1)
                .scaleY(1f)
                .zBy(1f)
                .z(0f).duration = 100
        }

    }
}